-- 优化秒杀Lua脚本
-- KEYS[1]: stockKey - 库存键 seckill:stock:voucherId
-- KEYS[2]: orderKey - 订单集合键 seckill:orders:voucherId
-- KEYS[3]: lockKey - 用户锁键 seckill:lock:voucherId:userId
-- ARGV[1]: voucherId - 优惠券Id
-- ARGV[2]: userId - 用户Id
-- 返回值：0=成功 1=库存不足 2=重复下单

-- 获取参数
local voucherId = ARGV[1]
local userId = ARGV[2]

-- Redis key定义
local stockKey = KEYS[1]  -- seckill:stock:voucherId
local orderKey = KEYS[2]  -- seckill:orders:voucherId
local lockKey = KEYS[3]   -- seckill:lock:voucherId:userId

-- 先检查库存是否充足（快速失败）
local stock = tonumber(redis.call('GET', stockKey) or 0)
if stock <= 0 then
    return 1  -- 库存不足，直接返回
end

-- 检查用户是否已购买（防止重复下单）
if redis.call('SISMEMBER', orderKey, userId) == 1 then
    return 2  -- 重复下单
end

-- 获取用户分布式锁（防止同一用户并发请求）
-- 锁超时时间设置为3秒，避免死锁
local lockResult = redis.call('SET', lockKey, userId, 'PX', 3000, 'NX')
if not lockResult then
    return 2  -- 获取锁失败，视为重复请求
end

-- 在锁保护下再次检查库存（双重检查）
stock = tonumber(redis.call('GET', stockKey) or 0)
if stock <= 0 then
    -- 释放锁
    redis.call('DEL', lockKey)
    return 1  -- 库存不足
end

-- 再次检查用户是否已购买（双重检查）
if redis.call('SISMEMBER', orderKey, userId) == 1 then
    -- 释放锁
    redis.call('DEL', lockKey)
    return 2  -- 重复下单
end

-- 原子操作：扣减库存、记录用户订单
redis.call('DECR', stockKey)
redis.call('SADD', orderKey, userId)

-- 释放锁
redis.call('DEL', lockKey)

return 0  -- 秒杀成功